# 方法一
# 如果密码含有@或者\，
# @ 我们可以使用 %40 替换，
# / 用 %2F 替换，
# \ 用 %5C 替换

# 方法二
# 当 DBURL 中存的密码部分存在特殊字符时需要通过编码后将其传入，否则会导致 DBURL 解析失败。
from sqlalchemy import create_engine

# 正常 sqlalchemy引擎
# connstr = "mysql+pymysql://root:root@127.0.0.1:3306/zjdata"


# # 演示当密码中包含@和/特殊字符时导致创建Engine对象失败
# dburl = "mysql+pymysql://testuser:123@456/!@127.0.0.1:3306/dbtest1"
# engine = create_engine(url=dburl, encoding='utf8')
# print(engine.connect())  # 报错：Can't connect to MySOL server on 456 ([Error 11001] getaddrinfo failed)


# 为了解决这个问题，可以先将带有特殊字符的密码部分进行编码，然后将编码后的密码传入url中。
import urllib.parse


# 对还有特殊字符的密码进行编码
def encode_pwd(pwd: str) -> str:
    encode_password = urllib.parse.quote_plus(pwd)
    print(encode_password)
    return encode_password


# 生成dburl
def get_dburl(pwd: str) -> str:
    password = encode_pwd(pwd)
    return f"mysql+pymysql://testuser:{password}@127.0.0.1:3306/dbtest1"


engine = create_engine(url=get_dburl('123@456/!'), encoding='utf8')
print(engine.connect())
